<html>

<style>
    * {
        margin: 0;
    }

    #content {
        color: white;
        position: absolute;
        left: -20px;
        top: -10px;
        white-space: pre-wrap;
        height: 200px;
        overflow: auto;
    }
</style>

<script type="importmap">
	{
	  "imports": {
		"three": "../../../three.js-r151/build/three.module.js",
		"three/addons/": "../../../three.js-r151/examples/jsm/"
	  }
	}
</script>

<body>
    <div id="content">
        真神奇，还挺像胳膊运动。
        假如不用外部动画，自己手写：
        模型表面顶点数据跟着虚拟的骨骼关节Bone发生变化，比如一个骨骼关节Bone转动，
        附近的皮肤(模型顶点)跟着旋转变形。
    </div>
    <div id="canvas"></div>

    <script type="module">
        import * as THREE from 'three';
        import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

        // 1. 必须创建的三大件
        // 1.1 三维场景Scene, 类似创建了个世界，三维世界
        const scene = new THREE.Scene();
        const geometry = new THREE.BoxGeometry(1, 1, 1);
        const material = new THREE.MeshBasicMaterial({ color: 'yellow' });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        // 添加辅助坐标系
        const axesHelper = new THREE.AxesHelper(5);
        scene.add(axesHelper);

        // 1.2 相机
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(3, 3, 3)

        // 1.3 渲染器
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        let canvasDom = document.getElementById("canvas");
        canvasDom.appendChild(renderer.domElement);

        function render() {
            renderer.render(scene, camera);
            requestAnimationFrame(render)
        }
        render();

        // 2. 设置相机控件轨道控制器OrbitControls
        new OrbitControls(camera, canvasDom);

        // 3. bone
        // 3.1 骨骼关节Bone树结构
        const bone1 = new THREE.Bone(); //关节1，用来作为根关节
        //平移Bone1，Bone2、Bone3跟着平移
        bone1.position.set(1, -0.5, 0);

        const bone2 = new THREE.Bone(); //关节2
        // 设置关节父子关系   多个骨头关节构成一个树结构
        bone1.add(bone2);
        // bone1.add(new THREE.AxesHelper(0.5))
        // 这个位置是相对于bone1的
        bone2.position.set(0, 1, 0)

        const bone3 = new THREE.Bone(); //关节3
        // bone2.add(new THREE.AxesHelper(0.5))
        bone3.position.z = 2
        bone2.add(bone3)


        // 骨骼关节旋转
        bone1.rotateX(-Math.PI / 6);
        // bone2.rotateX(Math.PI / 6);

        // 3.3 SkeletonHelper可视化骨骼关节
        // 骨骼关节可以和普通网格模型一样作为其他模型子对象，添加到场景中


        // SkeletonHelper会可视化参数模型对象所包含的所有骨骼关节
        const skeletonHelper = new THREE.SkeletonHelper(bone1);
        scene.add(bone1)
        scene.add(skeletonHelper)

        // 可视化控制
        import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
        const gui = new GUI();
        gui.add(bone1.rotation, 'x', 0, Math.PI / 3).name('关节1');
        gui.add(bone2.rotation, 'x', 0, Math.PI).name('关节2');

    </script>
</body>

</html>